package Thread;

//阻塞队列
class MyBlockingQueue{
    private String[] elems=null;
    private int head=0;
    private int tail=0;
    private int size=0;
    //准备锁对象
    private Object locker=new Object();
    public MyBlockingQueue(int capacity){
        elems=new String[capacity];
    }
    public void put(String elem) throws InterruptedException {
        //锁加到这里和加到方法上本质是一样的，加到方法上是给this加锁，此处是给locker加锁
        synchronized (locker){
            //改为while循环意味着wait唤醒之后再判定一次条件
            //wait之前判定一次，唤醒之后判定一次，再次确认，发现队列还是满着的，就继续等待
            while(size>=elems.length){
                //队列满了
                //后续需要这个代码阻塞
                locker.wait();
            }
            //新的元素要放到tail指向的位置上
            elems[tail]=elem;
            tail++;
            if(tail>=elems.length){
                tail=0;
            }
            size++;
            //入队列成功之后唤醒
            locker.notify();
        }
    }
    public String take() throws InterruptedException {
        String elem=null;
        synchronized (locker){
            while(size==0)
            {
                //队列空了
                //后续也需要让这个代码阻塞
                locker.wait();
            }
            //取出head位置的元素并返回
            elem=elems[head];
            head++;
            if(head>=elems.length){
                head=0;
            }
            size--;
            //元素出队列成功，加上唤醒
            locker.notify();
        }
        return elem;
    }
}

public class TreadDemo25 {
    public static void main(String[] args) throws InterruptedException {
        MyBlockingQueue queue=new MyBlockingQueue(1000);
        queue.put("aaa");
        queue.put("bbb");
        queue.put("ccc");
        queue.put("ddd");
        String elem="";
        elem=queue.take();
        System.out.println("elem:"+elem);
        elem=queue.take();
        System.out.println("elem:"+elem);
        elem=queue.take();
        System.out.println("elem:"+elem);
        elem=queue.take();
        System.out.println("elem:"+elem);
    }
}
